pythonでValue Objectを作りたい
結論.icon python標準ライブラリであるdataclassを使えば簡単にできる
値オブジェクトとは、以下6つの条件を持つオブジェクトのこと
1. ドメイン内の何かを計測したり定量化したり説明したりする
2. 状態を不変に保つことができる
3. 関連する属性を不可欠な単位として組み合わせることで、概念的な統一体を形成する
4. 計測値や説明が変わったときには、全体を完全に置き換えられる
5. 値が等しいかどうかを、他と比較できる
6. 協力関係にあるその他の概念に「副作用のない振る舞い」を提供する
以下のようなコードでValueObjectクラスを作成し、このクラスを値オブジェクトにしたいクラスに継承させる
code: value_object.py
from abc import ABCMeta, abstractmethod
from dataclasses import dataclass
# dataclassでデコレートすることで、使いやすいものに
@dataclass(frozen=True)
class ValueObject(metaclass=ABCMeta):
VALID_SCHEMA = {}
@classmethod
@abstractmethod
def new(cls, *args, **kwargs):
"""値の初期化に介入するクラスメソッド
例えば、「None」などが与えられた時に、それをコンバートする処理などをここで書く
"""
pass
def __post_init__(self):
"""値のバリデーションをこのメソッドで行う"""
# 以下は参考
# if len(self.name) > 10:
# raise ValueError
code: name.py
from dataclasses import dataclass
import .value_object import ValueObject
@dataclass(frozen=True)
class Name(ValueObject):
name: str
@classmethod
def new(cls, name: str | None):
"""値の初期化に介入するクラスメソッド
例えば、「None」などが与えられた時に、それをコンバートする処理などをここで書く
"""
if name is None:
name = ''
return cls(name=name)
代替案
NamedTupleを使う手も、どっかの記事で紹介されてたが...
記述が冗長になるのと、そのオブジェクトが使いにくそうだったので却下
参考
memo.icon
__new__ていうマジックメソッドには、どんな効果があるの?onigiri.w2.icon